import { stringifyQuery } from "@/utils/index.js"

export class Router {
  /**
   * 私有跳转方法
   * @param {String} state 跳转方式的类型
   * @param {String} path 路径
   * @param {Object} params 参数
   * @param {Object} options 配置项
   */
  _navTo ({ state, path, params, options = {} } = {}) {
    if (state !== "back") {
      if (!path) throw new Error("请传入 path！")
      options.url = path + stringifyQuery(params)
    }
    // 根据state来执行不同的操作
    switch (state) {
      case "page": {
        return uni.navigateTo(options)
      }
      case "redirect": {
        return uni.redirectTo(options)
      }
      case "reLaunch": {
        return uni.reLaunch(options)
      }
      case "tab": {
        return uni.switchTab(options)
      }
      case "back": {
        return uni.navigateBack(options)
      }
      case "preloadPage": {
        return uni.preloadPage(options)
      }
    }
  }

  /**
   * 保留当前页面，跳转到应用内的某个页面。
   * @param {String} path 路径
   * @param {Object} params 参数
   * @param {Object} ...rest 其余配置项
   */
  toPage ({ path, params, ...rest } = {}) {
    return this._navTo({ state: "page", path, params, options: rest })
  }

  /**
   * 关闭当前页面，跳转到应用内的某个页面。
   * @param {String} path 路径
   * @param {Object} params 参数
   */
  redirect ({ path, params } = {}) {
    return this._navTo({ state: "redirect", path, params })
  }

  /**
   * 关闭所有页面，打开到应用内的某个页面。
   * @param {String} path 路径
   * @param {Object} params 参数
   */
  reLaunch ({ path, params } = {}) {
    return this._navTo({ state: "reLaunch", path, params })
  }

  /**
   * 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面。
   * @param {String} path 路径
   * @param {Object} params 参数
   */
  toTab ({ path, params } = {}) {
    return this._navTo({ state: "tab", path, params })
  }

  /**
   * 关闭当前页面，返回上一页面或多级页面。
   * @param {String} backNum 返回的页面数，如果大于现有页面数，则返回到首页。
   * @param {Object} options 其余配置项
   */
  back (backNum = 1, options) {
    return this._navTo({
      state: "back",
      options: { delta: backNum, ...options },
    })
  }

  /**
   * 预加载页面，是一种性能优化技术。
   * @param {String} path 路径
   * @param {Object} params 参数
   */
  preloadPage ({ path, params } = {}) {
    return this._navTo({ state: "preloadPage", path, params })
  }
}
